#ifndef GUI_H
#define GUI_H

#pragma once

#include <msclr\marshal_cppstd.h>
#include <boost\date_time.hpp>

namespace Scheduler {

	#include "Logic.h"
	#include "Task.h"
	#include "Item.h"
	#include <string>
	#include <vector>
	#include <time.h>

	using namespace System;
	using namespace System::ComponentModel;
	using namespace System::Collections;
	using namespace System::Windows::Forms;
	using namespace System::Data;
	using namespace System::Drawing;
	using namespace boost::posix_time;

	/// <summary>
	/// Summary for Form1
	/// </summary>
	public ref class Form1 : public System::Windows::Forms::Form
	{
		Logic* logic;
		vector<Task>* displayVectorPtr;

	public:
	
		Form1()
		{
			InitializeComponent();
			//
			//TODO: Add the constructor code here
			//
			logic = new Logic();
			displayVectorPtr = new vector<Task>;
		}

		

	protected:
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		~Form1()
		{
			if (components)
			{
				delete components;
			}
			delete logic;
			delete displayVectorPtr;
		}

	private: System::Windows::Forms::TextBox^  textBox;
	private: System::Windows::Forms::Label^  label;
	private: System::Windows::Forms::Label^  status;
	private: System::Windows::Forms::PictureBox^  pictureBox1;
	private: BrightIdeasSoftware::MultiImageRenderer^  multiImageRenderer1;
	private: BrightIdeasSoftware::ObjectListView^  objectListView;
	private: BrightIdeasSoftware::OLVColumn^  index;
	private: BrightIdeasSoftware::OLVColumn^  done;

	private: BrightIdeasSoftware::OLVColumn^  taskName;
	private: BrightIdeasSoftware::OLVColumn^  priority;
	private: BrightIdeasSoftware::OLVColumn^  dateFrom;
	private: BrightIdeasSoftware::OLVColumn^  dateTo;
	private: System::Windows::Forms::ImageList^  imageList;
	private: BrightIdeasSoftware::MultiImageRenderer^  multiImageRenderer2;
	private: System::ComponentModel::IContainer^  components;
	private:
		/// <summary>
		/// Required designer variable.
		/// </summary>


#pragma region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		void InitializeComponent(void)
		{
			this->components = (gcnew System::ComponentModel::Container());
			System::ComponentModel::ComponentResourceManager^  resources = (gcnew System::ComponentModel::ComponentResourceManager(Form1::typeid));
			this->textBox = (gcnew System::Windows::Forms::TextBox());
			this->label = (gcnew System::Windows::Forms::Label());
			this->status = (gcnew System::Windows::Forms::Label());
			this->pictureBox1 = (gcnew System::Windows::Forms::PictureBox());
			this->imageList = (gcnew System::Windows::Forms::ImageList(this->components));
			this->multiImageRenderer1 = (gcnew BrightIdeasSoftware::MultiImageRenderer());
			this->objectListView = (gcnew BrightIdeasSoftware::ObjectListView());
			this->index = (gcnew BrightIdeasSoftware::OLVColumn());
			this->done = (gcnew BrightIdeasSoftware::OLVColumn());
			this->multiImageRenderer2 = (gcnew BrightIdeasSoftware::MultiImageRenderer());
			this->taskName = (gcnew BrightIdeasSoftware::OLVColumn());
			this->priority = (gcnew BrightIdeasSoftware::OLVColumn());
			this->dateFrom = (gcnew BrightIdeasSoftware::OLVColumn());
			this->dateTo = (gcnew BrightIdeasSoftware::OLVColumn());
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->pictureBox1))->BeginInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->objectListView))->BeginInit();
			this->SuspendLayout();
			// 
			// textBox
			// 
			this->textBox->AutoCompleteCustomSource->AddRange(gcnew cli::array< System::String^  >(1) {L"Type your command here"});
			this->textBox->AutoCompleteSource = System::Windows::Forms::AutoCompleteSource::CustomSource;
			this->textBox->Font = (gcnew System::Drawing::Font(L"Calibri", 11.25F, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, 
				static_cast<System::Byte>(0)));
			this->textBox->ForeColor = System::Drawing::Color::Silver;
			this->textBox->Location = System::Drawing::Point(12, 320);
			this->textBox->Name = L"textBox";
			this->textBox->Size = System::Drawing::Size(670, 26);
			this->textBox->TabIndex = 1;
			this->textBox->Text = L"Type your command here";
			this->textBox->Enter += gcnew System::EventHandler(this, &Form1::textBox_Enter);
			this->textBox->KeyPress += gcnew System::Windows::Forms::KeyPressEventHandler(this, &Form1::textBox_KeyPress);
			this->textBox->Leave += gcnew System::EventHandler(this, &Form1::textBox_Leave);
			// 
			// label
			// 
			this->label->AutoSize = true;
			this->label->Font = (gcnew System::Drawing::Font(L"Brush Script MT", 27.75F, static_cast<System::Drawing::FontStyle>((System::Drawing::FontStyle::Bold | System::Drawing::FontStyle::Italic)), 
				System::Drawing::GraphicsUnit::Point, static_cast<System::Byte>(0)));
			this->label->ForeColor = System::Drawing::Color::Green;
			this->label->Location = System::Drawing::Point(68, 12);
			this->label->Name = L"label";
			this->label->Size = System::Drawing::Size(200, 46);
			this->label->TabIndex = 3;
			this->label->Text = L"Scheduler++";
			// 
			// status
			// 
			this->status->AutoEllipsis = true;
			this->status->AutoSize = true;
			this->status->Font = (gcnew System::Drawing::Font(L"Calibri", 9, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, 
				static_cast<System::Byte>(0)));
			this->status->ForeColor = System::Drawing::SystemColors::HotTrack;
			this->status->Location = System::Drawing::Point(9, 349);
			this->status->Name = L"status";
			this->status->Size = System::Drawing::Size(145, 14);
			this->status->TabIndex = 4;
			this->status->Text = L"Welcome to Scheduler++!";
			// 
			// pictureBox1
			// 
			this->pictureBox1->Image = (cli::safe_cast<System::Drawing::Image^  >(resources->GetObject(L"pictureBox1.Image")));
			this->pictureBox1->Location = System::Drawing::Point(12, 8);
			this->pictureBox1->Name = L"pictureBox1";
			this->pictureBox1->Size = System::Drawing::Size(50, 50);
			this->pictureBox1->SizeMode = System::Windows::Forms::PictureBoxSizeMode::Zoom;
			this->pictureBox1->TabIndex = 5;
			this->pictureBox1->TabStop = false;
			// 
			// imageList
			// 
			this->imageList->ImageStream = (cli::safe_cast<System::Windows::Forms::ImageListStreamer^  >(resources->GetObject(L"imageList.ImageStream")));
			this->imageList->TransparentColor = System::Drawing::Color::Black;
			this->imageList->Images->SetKeyName(0, L"Star.bmp");
			this->imageList->Images->SetKeyName(1, L"Tick.bmp");
			// 
			// multiImageRenderer1
			// 
			this->multiImageRenderer1->ImageIndex = 0;
			this->multiImageRenderer1->ImageList = this->imageList;
			this->multiImageRenderer1->MaximumValue = 6;
			this->multiImageRenderer1->MaxNumberImages = 5;
			// 
			// objectListView
			// 
			this->objectListView->AllColumns->Add(this->index);
			this->objectListView->AllColumns->Add(this->done);
			this->objectListView->AllColumns->Add(this->taskName);
			this->objectListView->AllColumns->Add(this->priority);
			this->objectListView->AllColumns->Add(this->dateFrom);
			this->objectListView->AllColumns->Add(this->dateTo);
			this->objectListView->AllowColumnReorder = true;
			this->objectListView->AlternateRowBackColor = System::Drawing::Color::FromArgb(static_cast<System::Int32>(static_cast<System::Byte>(192)), 
				static_cast<System::Int32>(static_cast<System::Byte>(255)), static_cast<System::Int32>(static_cast<System::Byte>(192)));
			this->objectListView->AutoArrange = false;
			this->objectListView->BackColor = System::Drawing::Color::White;
			this->objectListView->BorderStyle = System::Windows::Forms::BorderStyle::None;
			this->objectListView->Columns->AddRange(gcnew cli::array< System::Windows::Forms::ColumnHeader^  >(6) {this->index, this->done, 
				this->taskName, this->priority, this->dateFrom, this->dateTo});
			this->objectListView->Cursor = System::Windows::Forms::Cursors::Default;
			this->objectListView->EmptyListMsg = L"display is empty";
			this->objectListView->EmptyListMsgFont = (gcnew System::Drawing::Font(L"Brush Script MT", 20.25F, static_cast<System::Drawing::FontStyle>((System::Drawing::FontStyle::Bold | System::Drawing::FontStyle::Italic)), 
				System::Drawing::GraphicsUnit::Point, static_cast<System::Byte>(0)));
			this->objectListView->Font = (gcnew System::Drawing::Font(L"Calibri", 9, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, 
				static_cast<System::Byte>(0)));
			this->objectListView->ForeColor = System::Drawing::Color::Green;
			this->objectListView->FullRowSelect = true;
			this->objectListView->HighlightBackgroundColor = System::Drawing::Color::Black;
			this->objectListView->HighlightForegroundColor = System::Drawing::Color::White;
			this->objectListView->Location = System::Drawing::Point(-2, 64);
			this->objectListView->Name = L"objectListView";
			this->objectListView->OverlayImage->Alignment = System::Drawing::ContentAlignment::BottomCenter;
			this->objectListView->OverlayText->Alignment = System::Drawing::ContentAlignment::BottomCenter;
			this->objectListView->OverlayText->BorderColor = System::Drawing::Color::Green;
			this->objectListView->OverlayText->Text = L"";
			this->objectListView->OverlayText->TextColor = System::Drawing::Color::Green;
			this->objectListView->OwnerDraw = true;
			this->objectListView->SelectedColumnTint = System::Drawing::Color::FromArgb(static_cast<System::Int32>(static_cast<System::Byte>(15)), 
				static_cast<System::Int32>(static_cast<System::Byte>(0)), static_cast<System::Int32>(static_cast<System::Byte>(64)), static_cast<System::Int32>(static_cast<System::Byte>(0)));
			this->objectListView->ShowGroups = false;
			this->objectListView->Size = System::Drawing::Size(695, 250);
			this->objectListView->Sorting = System::Windows::Forms::SortOrder::Ascending;
			this->objectListView->TabIndex = 6;
			this->objectListView->TintSortColumn = true;
			this->objectListView->UseAlternatingBackColors = true;
			this->objectListView->UseCompatibleStateImageBehavior = false;
			this->objectListView->UseTranslucentSelection = true;
			this->objectListView->View = System::Windows::Forms::View::Details;
			// 
			// index
			// 
			this->index->AspectName = L"INDEX";
			this->index->Text = L"Index";
			// 
			// done
			// 
			this->done->AspectName = L"DONE";
			this->done->HeaderTextAlign = System::Windows::Forms::HorizontalAlignment::Center;
			this->done->ImageAspectName = L"DONE";
			this->done->Renderer = this->multiImageRenderer2;
			this->done->Text = L"Done";
			this->done->TextAlign = System::Windows::Forms::HorizontalAlignment::Center;
			// 
			// multiImageRenderer2
			// 
			this->multiImageRenderer2->ImageIndex = 1;
			this->multiImageRenderer2->ImageList = this->imageList;
			this->multiImageRenderer2->MaximumValue = 1;
			this->multiImageRenderer2->MaxNumberImages = 1;
			// 
			// taskName
			// 
			this->taskName->AspectName = L"TASKNAME";
			this->taskName->Text = L"Task Name";
			this->taskName->Width = 180;
			// 
			// priority
			// 
			this->priority->AspectName = L"PRIORITY";
			this->priority->AspectToStringFormat = L"";
			this->priority->ImageAspectName = L"PRIORITY";
			this->priority->Renderer = this->multiImageRenderer1;
			this->priority->Text = L"Priority";
			this->priority->Width = 120;
			// 
			// dateFrom
			// 
			this->dateFrom->AspectName = L"DATEFROM";
			this->dateFrom->Text = L"From";
			this->dateFrom->Width = 120;
			// 
			// dateTo
			// 
			this->dateTo->AspectName = L"DATETO";
			this->dateTo->Text = L"To";
			this->dateTo->Width = 120;
			// 
			// Form1
			// 
			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
			this->AutoSize = true;
			this->BackColor = System::Drawing::SystemColors::Control;
			this->ClientSize = System::Drawing::Size(694, 372);
			this->Controls->Add(this->objectListView);
			this->Controls->Add(this->pictureBox1);
			this->Controls->Add(this->status);
			this->Controls->Add(this->label);
			this->Controls->Add(this->textBox);
			this->Font = (gcnew System::Drawing::Font(L"Calibri", 8.25F, System::Drawing::FontStyle::Regular, System::Drawing::GraphicsUnit::Point, 
				static_cast<System::Byte>(0)));
			this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::FixedSingle;
			this->Icon = (cli::safe_cast<System::Drawing::Icon^  >(resources->GetObject(L"$this.Icon")));
			this->MaximizeBox = false;
			this->Name = L"Form1";
			this->Text = L"Scheduler++";
			this->Load += gcnew System::EventHandler(this, &Form1::Form1_Load);
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->pictureBox1))->EndInit();
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->objectListView))->EndInit();
			this->ResumeLayout(false);
			this->PerformLayout();

		}
#pragma endregion

private: String^ convertStdStringToSysString(std::string stdstring)
		 {
				string Model(stdstring);
				String^ sysString = gcnew String(Model.c_str());
				return sysString;
		 }

private: std::string convertSysStringToStdString(String^ sysString)
		 {
			 	msclr::interop::marshal_context context;
				string stdString = context.marshal_as<string>(sysString);
				return stdString;
		 }

private: Object^ initializeItem(int i, Task task)
		 {
				bool done = task.getDone();
				String^ taskName = convertStdStringToSysString(task.getTaskName());
				int priority = task.getPriority();

				string stdStartTime = to_simple_string(task.getStartTime());
				String^ sysStartTime = convertStdStringToSysString(stdStartTime);

				string stdEndTime = to_simple_string(task.getEndTime());
				String^ sysEndTime = convertStdStringToSysString(stdEndTime);

				Object^ item = gcnew Item(i+1, done, taskName, priority, sysStartTime, sysEndTime);
				return item;
		 }

private: System::Void textBox_Enter(System::Object^  sender, System::EventArgs^  e) {
			 if(textBox->ForeColor == System::Drawing::Color::Silver)
			 {
				 textBox->Text = "";
				 textBox->ForeColor = System::Drawing::Color::Green;
			 }
		 }
private: System::Void textBox_Leave(System::Object^  sender, System::EventArgs^  e) {
			 if(textBox->Text == "")
			 {
				 textBox->ForeColor = System::Drawing::Color::Silver;
				 textBox->Text = "Type your command here";
			 }
		 }

private: System::Void Form1_Load(System::Object^  sender, System::EventArgs^  e) {
			//logic->setup();

		 }
private: System::Void textBox_KeyPress(System::Object^  sender, System::Windows::Forms::KeyPressEventArgs^  e) {

			 if(e->KeyChar == (char)Keys::Enter)
			 {
					//Initialize user command
					string userCommand = convertSysStringToStdString(textBox->Text);

					vector<Task> displayVector = *displayVectorPtr;

					//Call logic API
					string stdFeedback = logic->executeUserCommand(userCommand, displayVector);

					status->Text = convertStdStringToSysString(stdFeedback);

					objectListView->ClearObjects();

					for(unsigned int i=0; i<displayVector.size(); i++)
					{
						//Create item from displayVector
						Object^ item = initializeItem(i, displayVector[i]);
						
						//Add item to objectListView
						objectListView->AddObject(item);
					}

					textBox->Clear();
					e->Handled = true;
			 }
		 }
};
}

#endif